//切片
//总结

/**
所有权 借用和切片的概念是rust可以在编译时保证内存安全的关键所在.
像其他系统级语言一样，Rust语言给予了程序员完善的内存使用控制能力。
 */


fn main() {
    println!("Hello, world!");

    let mut  s=String::from("hello world");
   let len_int= first_word(&s);    //索引5会被绑定到变量len_int上
    s.clear(); //这里的clear方法是将s字符串清空,变成为""
    println!("{}",len_int);

    //字符串切片  切片引用
    let _s1=String::from("hello world");
    let hello=&_s1[0..5];   //&_s1[0..5] 等价于 &_s1[..5]
    let world=&_s1[6..11];
    println!("{}",hello);
    println!("{}",world);


    let len =String::from("file");
    let len_len_int=len.len();   //获得字符串的总长度
    let len1=&len[1..len_len_int];  //1代表起始位置,  len_lenInt代表结束位置
    let len2=&len[1..];             //表示从位置1到结束位置
    println!("{}",len1);
    println!("{}",len2);


    let len =String::from("file");
    let len_len_int: usize =len.len();   //获得字符串的总长度
    let len1=&len[0..len_len_int];    //0代表起始位置,  len_lenInt代表结束位置
    let len2=&len[..];          //  &len[0..len_lenInt];  等价于&len[..];
    println!("{}",len1);
    println!("{}",len2);


    //second_word()方法 处理String类型
    let my_string=String::from("hello, world");
    let _test_str=second_word(&my_string);
    let _test_str1=second_word(&my_string[1..8]);

    //second_word()处理&str类型
    let my_str="hello world";
    let _my_str1=second_word(&my_str);
    let my_str1=second_word(&my_str[0..7]);
    println!("{}",_test_str1);
    println!("{}",my_str1);


    //数字切片
    let a=[1,2,3,4,5];
    let slice=&a[1..3];
    //打印的是slice的长度
    println!("{}",slice.len());  //这里的切片类型是&[i32]，它在内部存储了一个指向起始元素的引用及长度，这与字符串切片的工作机制完全一样


}
fn first_word(s:&String)->usize{
    let bytes=s.as_bytes();
    for (i,&item) in bytes.iter().enumerate()  {
        if item ==b' '{
            return  i;
        }
    }
    s.len()
}

//这个方法的&str类型可以同时处理String和&str两种类型
fn second_word(s:&str)->&str{
    let bytes =s.as_bytes();
    for (i,&irem) in bytes.iter().enumerate()  {
        if irem==b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}


